package com.av.rmi.impl;

import java.io.File;
import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.server.UnicastRemoteObject;
import java.rmi.server.Unreferenced;

import org.apache.log4j.Logger;

import com.av.acciones.BaseAccion;
import com.av.exceptions.AvException;
import com.av.rmi.Parametro;
import com.av.rmi.interfaces.ServerRemote;

/**
 * Implementacion de punto de entrada a funciones promovidas en el servidor
 * 
 * @author Victor J Morales R
 * 
 */
public class ServerRemoteImpl implements ServerRemote, Unreferenced {

	private static Logger log = Logger.getLogger(ServerRemoteImpl.class);
	private static final long serialVersionUID = 1L;
	private static final File f = new File("bin" + File.separator);

	protected ServerRemoteImpl() throws RemoteException {
		super();
		log.info("Inicio - ctor");

		log.info("Fin - ctor");
	}// ServerRemoteImpl

	@Override
	public Parametro ejecutar(Parametro param) throws RemoteException {
		log.info("Inicio - ejecutar(Parametro param)");

		BaseAccion accion = BaseAccion.getAccion(param.getAccion());
		Parametro p = null;
		if (accion != null) {
			log.debug("Ejecutar : " + param.getAccion());
			try {
				p = accion.ejecutar(param);
			} catch (AvException e) {
				log.error("Ha ocurrido un error al intentar ejecutar la accion");
				throw new RemoteException("Ha ocurrido un error al intentar "
						+ "ejecutar la accion", e);
			}
		} else {
			log.warn("Accion no encontrada");
		}

		log.info("Fin - ejecutar(Parametro param)");

		return p;
	}// ejecutar

	@Override
	public byte[] ejecutar(byte[] bytes) throws RemoteException {
		log.info("Inicio - ejecutar(byte[] bytes)");

		byte[] b = null;
		Parametro p = null;

		try {
			p = ejecutar(Parametro.descomprimir(bytes));
		} catch (AvException e) {
			log.error("Error al ejecutar el parametro", e);
		}

		try {
			b = Parametro.comprimir(p);
		} catch (AvException e) {
			log.error("Error al comprimir el parametro", e);
		}

		log.info("Fin - ejecutar(byte[] bytes)");

		return b;
	}// ejecutar

	public static void main(String[] args) {
		System.out.println("Starting server...");

		try {
			LocateRegistry.createRegistry(PORT);
		} catch (RemoteException e) {
			log.error("Ha ocurrido un error al ejecutar el comando rmiregistry",e);
		}

		System.setProperty("java.rmi.server.codebase", f.toURI().toString());
		System.setProperty("java.security.policy", "registerit.policy");
		System.setProperty("java.rmi.server.logCalls", "true");

		ServerRemoteImpl obj = null;

		try {
			// ServerRemote stub = (ServerRemote) UnicastRemoteObject
			// .exportObject(obj, 0,
			// new ZipClientSocketFactory(),
			// new ZipServerSocketFactory());
			obj = new ServerRemoteImpl();
			ServerRemote stub = (ServerRemote) UnicastRemoteObject
					.exportObject(obj, 0);

			Naming.rebind(OBJECT_STUB_REGISTRY_NAME, stub);
			System.out.println("Server ready");
		} catch (Exception e) {
			log.error("Ha ocurrido un error al registrar el servicio", e);
		}
	}// main

	@Override
	public void unreferenced() {
		log.warn("Ha sido recolectado por el GC");
	}// unreferenced
}// ServerRemoteImpl
